//
//  ZFSegmentControl.m
//  PageHolder
//
//  Created by 赵梁 on 2017/1/3.
//  Copyright © 2017年 赵梁. All rights reserved.
//

#import "ZFSegmentControl.h"

#define ZFSegmentControlHspace (12)
#define ZFSegmentControlAnimationTime (0.3)

@interface ZFSegmentControl () <UIScrollViewDelegate>

@property (nonatomic, strong) UIScrollView *contentView;//!< <#描述#>
@property (nonatomic, strong) UIView *lineView;//!< <#描述#>


@property (nonatomic, strong) NSMutableArray<UIView*> *itemViews;//!< <#描述#>
@property (nonatomic, assign) NSInteger currentIndex;//!< <#描述#>

@end

@implementation ZFSegmentControl

#pragma mark -
#pragma mark Initialisation

- (void)setUp
{
    _lineColor = [UIColor clearColor];
    _lineHeight = 3;
    
    _contentView = ({
        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
        scrollView.backgroundColor = [UIColor clearColor];
        scrollView.delegate = self;
        scrollView.showsHorizontalScrollIndicator = NO;
        scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        scrollView.bounces = NO;
        [self addSubview:scrollView];
        
        scrollView;
    });
    
    //add tap gesture recogniser
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)];
    tapGesture.delegate = (id <UIGestureRecognizerDelegate>)self;
    [_contentView addGestureRecognizer:tapGesture];
    
    //set up accessibility
    self.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction;
    self.isAccessibilityElement = YES;
    
    [self addSubview:_contentView];
    
    if (_dataSource)
    {
        [self reloadData];
    }
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if ((self = [super initWithCoder:aDecoder]))
    {
        [self setUp];
        if (self.superview)
        {
            
        }
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        [self setUp];
    }
    return self;
}

- (void)dealloc
{
    
}

#pragma mark - view loading
- (void)reloadData
{
    //layout views
    [self setNeedsLayout];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    _contentView.frame = self.bounds;
    [self layOutItemViews];
}

- (void)layOutItemViews
{
    //remove old views
    for (UIView *view in self.itemViews)
    {
        [view.superview removeFromSuperview];
    }
    
    //bail out if not set up yet
    if (!_dataSource || !_contentView)
    {
        return;
    }
    
    [self.itemViews removeAllObjects];
    
    NSInteger numberOfItems = self.numberOfItems;
    CGFloat width = 0;
    for (NSInteger index=0; index<numberOfItems; index++) {
        
        UIView *cell = [_dataSource zf_segmentControl:self viewForItemAtIndex:index reusingView:nil didSelected:_currentIndex==index];
        NSAssert(cell!=nil, @"@selector(zf_segmentControl:viewForItemAtIndex:reusingView:didSelected:) retrun nil");
        
        CGRect frame = cell.frame;
        frame.origin = CGPointMake(width, 0);
        cell.frame = frame;
        [_contentView addSubview:cell];
        
        width += cell.frame.size.width;
        
        [self.itemViews addObject:cell];
    }
    [_contentView setContentSize:CGSizeMake(width, _contentView.frame.size.height)];
    
    [self selectIndex:_currentIndex];
}

#pragma mark - action

- (void)didTap:(UITapGestureRecognizer *)sender
{
    CGPoint point = [sender locationInView:sender.view];
    
    __weak typeof(self) weakSelf = self;
    [self.itemViews enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        CGRect rect = [obj frame];
        
        if (CGRectContainsPoint(rect, point)) {
            
            [weakSelf selectIndex:idx];
            [weakSelf transformAction:idx];
            *stop = YES;
        }
    }];
}

- (void)transformAction:(NSInteger)index
{
    if (_delegate && [_delegate conformsToProtocol:@protocol(ZFSegmentControlDelegate)]
        && [_delegate respondsToSelector:@selector(zf_segmentControl:didSelectedIndex:)]) {
        [_delegate zf_segmentControl:self didSelectedIndex:index];
    }
}

- (void)addRedLineWithAnimations:(BOOL)animations
{
    if (!_lineView) {
        
        _lineView = [[UIView alloc] initWithFrame:CGRectZero];
        _lineView.backgroundColor = _lineColor;
        [_contentView addSubview:_lineView];
    }
    
    UIView *cell = self.itemViews[_currentIndex];
    
    CGRect rect = cell.frame;
    CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + ZFSegmentControlHspace, CGRectGetHeight(rect) - _lineHeight, CGRectGetWidth(rect) - 2 * ZFSegmentControlHspace, _lineHeight);
    
    if (animations) {
        [UIView animateWithDuration:ZFSegmentControlAnimationTime animations:^{
            _lineView.frame = lineRect;
        }];
    }else {
        _lineView.frame = lineRect;
    }
}

- (void)selectIndex:(NSInteger)index
{
    if (index != _currentIndex) {
        [self reloadItemViewAtIndex:_currentIndex didSelect:NO];
        [self reloadItemViewAtIndex:index didSelect:YES];
        
        _currentIndex = index;
        [self addRedLineWithAnimations:YES];
    }else {
        [self addRedLineWithAnimations:NO];
    }
    [self setScrollOffset:index];
}

- (void)moveIndexWithProgress:(float)progress
{
    float delta = progress - _currentIndex;
    
    NSInteger deltaInt = 0;
    if (delta > 0) {
        
        if (_currentIndex == self.numberOfItems - 1) {
            return;
        }
        
        deltaInt = 1;
    }else if (delta < 0){
        
        if (_currentIndex == 0) {
            return;
        }
        deltaInt = -1;
    }
    CGRect origionRect = [_itemViews[_currentIndex] frame];
    
    CGRect origionLineRect = CGRectMake(CGRectGetMinX(origionRect) + ZFSegmentControlHspace, CGRectGetHeight(origionRect) - _lineHeight, CGRectGetWidth(origionRect) - 2 * ZFSegmentControlHspace, _lineHeight);
    
    
    CGRect rect = [self.itemViews[_currentIndex + deltaInt] frame];
    CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + ZFSegmentControlHspace, CGRectGetHeight(rect) - _lineHeight, CGRectGetWidth(rect) - 2 * ZFSegmentControlHspace, _lineHeight);
    
    CGRect moveRect = CGRectZero;
    moveRect.size = CGSizeMake(CGRectGetWidth(origionLineRect) + fabsf(delta) * (CGRectGetWidth(lineRect) - CGRectGetWidth(origionLineRect)), CGRectGetHeight(lineRect));
    
    _lineView.frame = moveRect;
    _lineView.center = CGPointMake(CGRectGetMidX(origionLineRect) + fabsf(delta)  * (CGRectGetMidX(lineRect) - CGRectGetMidX(origionLineRect)), CGRectGetMidY(origionLineRect));
    
    if (fabsf(delta) >= 1) {
        [self selectIndex:_currentIndex+deltaInt];
    }
}

- (void)endMoveIndex:(NSInteger)index
{
    [self selectIndex:index];
}

- (void)setScrollOffset:(NSInteger)index
{
    CGRect rect = [self.itemViews[index] frame];
    
    float midX = CGRectGetMidX(rect);
    
    float offset = 0;
    
    float contentWidth = _contentView.contentSize.width;
    
    float halfWidth = CGRectGetWidth(self.bounds) / 2.0;
    
    if (midX < halfWidth) {
        offset = 0;
    }else if (midX > contentWidth - halfWidth){
        offset = contentWidth - 2 * halfWidth;
    }else{
        offset = midX - halfWidth;
    }
    
    [UIView animateWithDuration:ZFSegmentControlAnimationTime animations:^{
        [_contentView setContentOffset:CGPointMake(offset, 0) animated:NO];
    }];
}


- (void)reloadItemViewAtIndex:(NSInteger)index didSelect:(BOOL)didSelect
{
    UIView *cell = self.itemViews[index];
    if (cell) {
        [cell removeFromSuperview];
    }
    
    if (!_dataSource) {
        return;
    }
    [self.itemViews removeObject:cell];
    CGRect oldFrame = cell.frame;
    cell = [_dataSource zf_segmentControl:self viewForItemAtIndex:index reusingView:cell didSelected:didSelect];
    [_contentView addSubview:cell];
    [self.itemViews insertObject:cell atIndex:index];
    
    if (!CGRectEqualToRect(oldFrame, cell.frame)) {
        [self resetItemViewsFrame];
    }
}

/**
 重新加载itemviews的frame
 */
- (void)resetItemViewsFrame
{
    CGFloat width = 0;
    for (UIView *cell in self.itemViews) {
        [cell removeFromSuperview];
        
        CGRect frame = cell.frame;
        frame.origin = CGPointMake(width, 0);
        cell.frame = frame;
        [_contentView addSubview:cell];
        //fix width is 0
        width = cell.frame.origin.x+cell.frame.size.width;
    }
    [_contentView setContentSize:CGSizeMake(width, _contentView.frame.size.height)];
    [self selectIndex:_currentIndex];
    [self setScrollOffset:_currentIndex];
}

#pragma mark - scrollView delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    
}

#pragma mark - getters & getters
- (NSMutableArray<UIView *> *)itemViews
{
    if (!_itemViews) {
        _itemViews = [NSMutableArray arrayWithCapacity:0];
    }
    return _itemViews;
}

- (NSInteger)numberOfItems
{
    if (_dataSource&&[_dataSource conformsToProtocol:@protocol(ZFSegmentControlDataSource)]&&[_dataSource respondsToSelector:@selector(numberOfItemsInZFSegmentControl:)]) {
        return [_dataSource numberOfItemsInZFSegmentControl:self];
    }
    return 0;
}

- (void)setDataSource:(id<ZFSegmentControlDataSource>)dataSource
{
    if (_dataSource != dataSource)
    {
        _dataSource = dataSource;
        if (_dataSource)
        {
            [self reloadData];
        }
    }
}

- (void)setDelegate:(id<ZFSegmentControlDelegate>)delegate
{
    if (_delegate != delegate)
    {
        _delegate = delegate;
        if (_delegate && _dataSource)
        {
            [self setNeedsLayout];
        }
    }
}

- (void)setLineColor:(UIColor *)lineColor
{
    _lineColor = lineColor;
    
    if (_lineView) {
        _lineView.backgroundColor = _lineColor;
    }
}

- (void)setLineHeight:(CGFloat)lineHeight
{
    _lineHeight = lineHeight;
    
    if (_dataSource) {
        [self addRedLineWithAnimations:NO];
    }
}


@end
